package com.srkj.activiti.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.srkj.activiti.entity.ProcessDefinitionEntity;
import com.srkj.activiti.service.ProcessService;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipInputStream;

/**
 * 流程定义管理
 * zhangshaoxiong
 * com.srkj.activiti.controller
 * 2018/6/2 13:53
 */
@Controller
@RequestMapping("processInstance")
public class ProcessInstancesController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ProcessService processService;
    /**
     * 跳转到列表页
     * @return
     */
    @RequestMapping("processInstanceList")
    public String processInstances(Model model){
        List<ProcessDefinition> processDefinitionlist = repositoryService.createProcessDefinitionQuery().orderByDeploymentId().asc().list();

        List<ProcessDefinitionEntity> processInstancelist = new ArrayList<>();
        for (ProcessDefinition processDefinition:processDefinitionlist) {
            ProcessDefinitionEntity pd = new ProcessDefinitionEntity();
            String deploymentId = processDefinition.getDeploymentId();
            Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
            pd.setId(processDefinition.getId());
            pd.setName(processDefinition.getName());
            pd.setDeploymentId(processDefinition.getDeploymentId());
            pd.setVersion(processDefinition.getVersion());
            pd.setResourceName(processDefinition.getResourceName());
            pd.setDiagramResourceName(processDefinition.getDiagramResourceName());
            pd.setDeploymentTime(deployment.getDeploymentTime());
            pd.setSuspended(processDefinition.isSuspended());
            processInstancelist.add(pd);
        }
        model.addAttribute("processInstances",processInstancelist);
        return "process/processInstanceList";
    }

    @PostMapping("redeploySingle")
    public String redeploySingle(MultipartFile file,Model model){
        String fileName = file.getOriginalFilename();
        int dian = fileName.lastIndexOf(".");
        String orname = fileName.substring(0, dian);
        try {
            Deployment deployment = null;
            InputStream inputStream = file.getInputStream();
            String extension = FilenameUtils.getExtension(fileName);
            if (extension.equals("zip") || extension.equals("bar")){
                ZipInputStream zip = new ZipInputStream(inputStream);
                deployment = this.repositoryService.createDeployment().addZipInputStream(zip).name(orname).deploy();
            }else{
                deployment = this.repositoryService.createDeployment().addInputStream(orname,inputStream).deploy();
            }
            model.addAttribute("message","上传成功");

        }catch (Exception e){

            model.addAttribute("message","上传失败");
        }
        return "redirect:/processInstance/processInstanceList";
    }

    /**
     * 查看图片及xml
     */
    @GetMapping("loadPic")
    public void loadPicByProcessDefinitionId(String processDefinitionId, @RequestParam(value = "resourceType",required = false) String resourceType,
                                             HttpServletResponse response) throws Exception{
        InputStream resourceAsStream = processService.getDiagramByProDefinitionId_noTrace(resourceType, processDefinitionId);
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b,0,1024)) != -1){
            response.getOutputStream().write(b,0,len);
        }
    }

    /**
     * 删除流程定义
     * @param deploymentId 部署ID
     * @return
     */
    @DeleteMapping("deleteProcessInstance/{deploymentId}")
    public String deleteProcessInstance(@PathVariable("deploymentId") String deploymentId){
        repositoryService.deleteDeployment(deploymentId,true);
        return "redirect:/processInstance/processInstanceList";
    }

    /**
     *流程挂起/激活
     * @param status 状态
     * @param pdid 流程定义ID
     * @throws Exception
     */
    @GetMapping("editStatus")
    public String editStatus(boolean status,String pdid) throws Exception{
        if (!status){
            repositoryService.activateProcessDefinitionById(pdid,true,null);
        }else if (status){
            repositoryService.suspendProcessDefinitionById(pdid,true,null);
        }
        return "redirect:/processInstance/processInstanceList";
    }

    /**
     * 转换为Model
     * @param processDefinitionId
     * @return
     */
    @RequestMapping("/convert_to_model")
    public String convertToModel(String processDefinitionId) throws Exception {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId).singleResult();
        InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),
                processDefinition.getResourceName());
        XMLInputFactory xif = XMLInputFactory.newInstance();
        InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
        XMLStreamReader xtr = xif.createXMLStreamReader(in);
        BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);

        BpmnJsonConverter converter = new BpmnJsonConverter();
        com.fasterxml.jackson.databind.node.ObjectNode modelNode = converter.convertToJson(bpmnModel);
        org.activiti.engine.repository.Model modelData = repositoryService.newModel();
        modelData.setKey(processDefinition.getKey());
        modelData.setName(processDefinition.getResourceName());
        modelData.setCategory(processDefinition.getDeploymentId());

        ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
        modelData.setMetaInfo(modelObjectNode.toString());

        repositoryService.saveModel(modelData);

        repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));

        return "redirect:/processInstance/processInstanceList";
    }






}
